/********************************************
 * 功能说明: OrganizationEmployee实体与DTO之间接口数据转换实现
 * 模块名称:
 * 系统名称:
 * 软件版权: Frank
 * 系统版本: 1.0.0.1
 * 开发人员:
 * 开发时间: 2019-12-18 18:41:08
 * 审核人员:
 * 相关文档:
 * 修改记录: 修改日期 修改人员 修改说明
 *********************************************/
package com.spring.arch.uaa.web.converter;

import com.spring.arch.common.converter.AbstractConverter;
import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.uaa.web.dto.WebOrganizationEmployeeDTO;
import com.spring.arch.common.converter.AbstractConverter;
import com.spring.arch.common.exception.ExceptionHolder;
import com.spring.arch.uaa.errorcode.UaaErrorCode;
import com.spring.arch.uaa.model.Organization;
import com.spring.arch.uaa.model.OrganizationEmployee;
import com.spring.arch.uaa.model.OrganizationEmployeeRole;
import com.spring.arch.uaa.model.TenantEmployee;
import com.spring.arch.uaa.repository.*;
import com.spring.arch.uaa.web.dto.WebOrganizationEmployeeDTO;
import lombok.NonNull;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import javax.persistence.EntityManager;
import java.util.List;

/**
 * OrganizationEmployee实体与DTO之间接口数据转换实现
 *
 * @author
 * @version 1.0.0.1
 * @since 2019-12-18 18:41:08
 */
@Component
public class WebOrganizationEmployeeConverter extends AbstractConverter<OrganizationEmployee,
        WebOrganizationEmployeeDTO> {

    @Autowired
    private OrganizationEmployeeRepository organizationEmployeeRepository;

    @Autowired
    private OrganizationRepository organizationRepository;

    @Autowired
    private TenantEmployeeRepository tenantEmployeeRepository;

    @Autowired
    private OrganizationEmployeeRoleRepository organizationEmployeeRoleRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private EntityManager entityManager;

    @Override
    public OrganizationEmployee toModel(@NonNull final WebOrganizationEmployeeDTO dto) {
        if(dto.isNew()) {
            return constructModel(dto);
        } else {
            return updateModel(dto);
        }
    }

    @Override
    public WebOrganizationEmployeeDTO toDTO(@NonNull final OrganizationEmployee model) {

        WebOrganizationEmployeeDTO dto = new WebOrganizationEmployeeDTO();

        dto.setId(model.getId());
        dto.setOrganizationId(model.getOrganization().getId());
        dto.setEmployeeId(model.getEmployee().getId());
        dto.setCode(model.getEmployee().getCode());
        dto.setName(model.getEmployee().getName());
        dto.setMobile(model.getEmployee().getMobile());
        dto.setGender(model.getEmployee().getGender());
        dto.setEmail(model.getEmployee().getEmail());
        dto.setStatus(model.getStatus());

        StringBuilder sb = new StringBuilder();

        List<OrganizationEmployeeRole> roleList = organizationEmployeeRoleRepository.findByOrganizationEmployee(model);
        roleList.forEach(l -> sb.append(l.getRole().getName()).append(","));

        dto.setRole(sb.length() == 0 ? null : sb.deleteCharAt(sb.length() - 1).toString());

        return dto;
    }

    /**
     * 构建新Model
     */
    private OrganizationEmployee constructModel(final WebOrganizationEmployeeDTO dto) {
        final OrganizationEmployee model = new OrganizationEmployee();
        this.dtoToModel(dto, model);
        return model;
    }

    /**
     * 更新Model
     */
    private OrganizationEmployee updateModel(final WebOrganizationEmployeeDTO dto) {
        final OrganizationEmployee model = this.organizationEmployeeRepository.findById(dto.getId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001,
                        OrganizationEmployee.class.getSimpleName()));

        entityManager.unwrap(Session.class).evict(model);
        this.dtoToModel(dto, model);
        return model;
    }

    private void dtoToModel(final WebOrganizationEmployeeDTO dto, final OrganizationEmployee model) {

        final Organization organization = this.organizationRepository.findById(dto.getOrganizationId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001003001,
                        dto.getOrganizationId().toString()));

        final TenantEmployee tenantEmployee = this.tenantEmployeeRepository.findById(dto.getEmployeeId())
                .orElseThrow(() -> ExceptionHolder.serviceException(UaaErrorCode.E2001001002,
                        dto.getEmployeeId().toString()));
        
        model.setUser(this.userRepository.findByMobile(tenantEmployee.getMobile()).orElse(null));
        model.setOrganization(organization);
        model.setEmployee(tenantEmployee);
    }
}
